from sys import exit, argv
# Could be re-written with C-Types            

class Interpreter:
    def __init__(self,program,ipt):
        self.program = program
        self.instruction_pointer = 0
        self.input = ipt.split()
        self.the_pointer = 0
        self.array = []
        self.subprogram = []
        self.subprogram_pointer = -1
        
        # Configuration variables
        self.array_size = 30000
        self.initial_value = 0
        self.cell_size = 255
        
        
        n = 0
        # init array
        while n < self.array_size:
            self.array.append(self.initial_value)
            n = n + 1
            
    def IncrementPointer(self):
        if self.the_pointer == (self.array_size)-1:
            self.the_pointer = 0
        else: 
            self.the_pointer = self.the_pointer + 1
    
    def DecrementPointer(self):
        if self.the_pointer == 0:
            self.the_pointer = self.array_size - 1
        else: 
            self.the_pointer = self.the_pointer - 1
            
    def IncrementByte(self):
        cell = self.array[self.the_pointer]
        if cell == self.cell_size:
            cell = 0
        else:
            cell = cell + 1
        self.array[self.the_pointer] = cell
        
    def DecrementByte(self):
        cell = self.array[self.the_pointer]
        if cell == 0:
            cell = self.cell_size
        else:
            cell = cell -1
        self.array[self.the_pointer] = cell
        
    
    def OutputByte(self):
        print chr(self.array[self.the_pointer]),
        #print self.array[self.the_pointer]

    def InputByte(self):
        try:
            ipt = ord(self.input.pop(0))
        except:
            ipt = 0
        
        self.array[self.the_pointer] = ipt
        
    def JumpFoward(self):
        # IF cell is zero, jump to the closing bracket
        # ELSE create subprogram, move current program into sub_program array
        # and make
        # USE CURRENT PROGRAM POSITIONS IN A TUPLE (0,n) next sub program (x,y)
        
        # Find closing bracket
        OBracket = 0
        CBracket = 0
        ptr = 0
        for cmd in self.program:
            ptr = ptr + 1
            
            if cmd == '[':
                OBracket = OBracket + 1
            elif cmd == ']':
                CBracket = CBracket + 1
                if CBracket == OBracket:
                    # Do the jump checks here
                    if self.array[self.the_pointer] == 0:
                        self.instruction_pointer = ptr+1
                    else:
                        self.subprogram.append((self.instruction_pointer,ptr))
                        self.subprogram_pointer = self.subprogram_pointer + 1
                    return 0
                
                
        print 'Unbalanced brackets'
        exit(-1)
                
                
                
        
        pass
    def JumpBack(self):
        if self.array[self.the_pointer] == 0:
            # Okay this is badly done but it works
            self.subprogram.pop(self.subprogram_pointer)
            self.subprogram_pointer = self.subprogram_pointer  -1
        else:
            self.instruction_pointer = self.subprogram[self.subprogram_pointer][0]
            
    def ProgramParser(self):
        try:
        #    cmd = self.program.pop(0)
            cmd = self.program[self.instruction_pointer]
        except:
            # Program is done
            exit(0)
        
        # > and < will wrap around the array
        if cmd == '>':
            self.IncrementPointer()
        elif cmd == '<':
            self.DecrementPointer()
        elif cmd == '.':
            self.OutputByte()
        elif cmd == ',':
            self.InputByte()
        elif cmd == '+':
            self.IncrementByte()
        elif cmd == '-':
            self.DecrementByte()
        elif cmd == '[':
            self.JumpFoward()
        elif cmd == ']':
            self.JumpBack()
        else:
            pass
        self.IncrementIP()
        
    def IncrementIP(self):
        #print self.instruction_pointer
        self.instruction_pointer = self.instruction_pointer + 1
    
    def Run(self):
        while True:
            self.ProgramParser()
        
if __name__ == "__main__":
    bf = Interpreter('++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.','z')
    #bf = Interpreter(',','z')
    
    bf.Run()
    
    